home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / freeWAIS-sf-1.1 / x / myAsciiSrc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-04  |  35.7 KB  |  1,372 lines

  1. /* Borrowed by Jonny Goldman. */
  2. /* $XConsortium: AsciiSrc.c,v 1.55 91/07/25 18:09:27 rws Exp $ */
  3. /*
  4.  * $Log: myAsciiSrc.c,v $
  5.  * Revision 1.4  1994/03/25  10:21:02  pfeifer
  6.  * now will try to make 8-bit chars work
  7.  *
  8.  * Revision 1.4  1994/03/25  10:21:02  pfeifer
  9.  * now will try to make 8-bit chars work
  10.  *
  11.  * Revision 1.2  93/07/01  18:19:07  warnock
  12.  * Fixed declaration in MyAsciiSaveAsFile for SGI/X11R4
  13.  * 
  14.  * Revision 1.1  93/02/16  15:10:18  freewais
  15.  * Initial revision
  16.  * 
  17.  * Revision 1.1  92/06/22  10:42:19  jonathan
  18.  * Initial revision
  19.  * 
  20.  */
  21.  
  22. /*
  23.  * Copyright 1989 Massachusetts Institute of Technology
  24.  *
  25.  * Permission to use, copy, modify, distribute, and sell this software and its
  26.  * documentation for any purpose is hereby granted without fee, provided that
  27.  * the above copyright notice appear in all copies and that both that
  28.  * copyright notice and this permission notice appear in supporting
  29.  * documentation, and that the name of M.I.T. not be used in advertising or
  30.  * publicity pertaining to distribution of the software without specific,
  31.  * written prior permission.  M.I.T. makes no representations about the
  32.  * suitability of this software for any purpose.  It is provided "as is"
  33.  * without express or implied warranty.
  34.  *
  35.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  36.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  37.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  38.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  39.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  40.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  41.  *
  42.  * Author:  Chris Peterson, MIT X Consortium.
  43.  *
  44.  * Much code taken from X11R3 String and Disk Sources.
  45.  */
  46.  
  47. /* Copyright (c) CNIDR (see ../COPYRIGHT) */
  48.  
  49.  
  50. /*
  51.  * AsciiSrc.c - AsciiSrc object. (For use with the text widget).
  52.  *
  53.  */
  54.  
  55. #include <X11/IntrinsicP.h>
  56. #include <stdio.h>
  57. #include <ctype.h>
  58. #include <errno.h>
  59. #include <X11/StringDefs.h>
  60. #include <X11/Xos.h>
  61. /*#include <X11/Xfuncs.h>*/
  62. #include <X11/Xaw/XawInit.h>
  63. #include "myAsciiSrcP.h"
  64. #include <X11/Xmu/Misc.h>
  65. #include <X11/Xmu/CharSet.h>
  66.  
  67. #if (defined(ASCII_STRING) || defined(ASCII_DISK))
  68. #  include <X11/Xaw/AsciiText.h> /* for Widget Classes. */
  69. #endif
  70.  
  71.  
  72. #ifndef XPointer
  73. #define XPointer caddr_t
  74. #endif
  75.  
  76. #ifndef XawLF
  77. #define XrmPermStringToQuark XrmStringToQuark
  78. #endif
  79.  
  80. /****************************************************************
  81.  *
  82.  * Full class record constant
  83.  *
  84.  ****************************************************************/
  85.  
  86. /* Private Data */
  87.  
  88. static int magic_value = MAGIC_VALUE;
  89.  
  90. #define offset(field) XtOffsetOf(MyAsciiSrcRec, ascii_src.field)
  91.  
  92. static XtResource resources[] = {
  93.     {XtNstring, XtCString, XtRString, sizeof (char *),
  94.        offset(string), XtRString, NULL},
  95.     {XtNtype, XtCType, XtRAsciiType, sizeof (XawAsciiType),
  96.        offset(type), XtRImmediate, (XtPointer)XawAsciiString},
  97.     {XtNdataCompression, XtCDataCompression, XtRBoolean, sizeof (Boolean),
  98.        offset(data_compression), XtRImmediate, (XtPointer) TRUE},
  99.     {XtNpieceSize, XtCPieceSize, XtRInt, sizeof (XawTextPosition),
  100.        offset(piece_size), XtRImmediate, (XtPointer) BUFSIZ},
  101.     {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer), 
  102.        offset(callback), XtRCallback, (XtPointer)NULL},
  103.     {XtNuseStringInPlace, XtCUseStringInPlace, XtRBoolean, sizeof (Boolean),
  104.        offset(use_string_in_place), XtRImmediate, (XtPointer) FALSE},
  105.     {XtNlength, XtCLength, XtRInt, sizeof (int),
  106.        offset(ascii_length), XtRInt, (XtPointer) &magic_value},
  107.  
  108. #ifdef ASCII_DISK
  109.     {XtNfile, XtCFile, XtRString, sizeof (String),
  110.        offset(filename), XtRString, NULL},
  111. #endif /* ASCII_DISK */
  112. };
  113. #undef offset
  114.  
  115. static XawTextPosition Scan(), Search(), ReadText();
  116. static int ReplaceText();
  117. static Piece * FindPiece(), * AllocNewPiece();
  118. static FILE * InitStringOrFile();
  119. static void FreeAllPieces(), RemovePiece(), BreakPiece(), LoadPieces();
  120. static void RemoveOldStringOrFile(),  CvtStringToAsciiType();
  121. static void ClassInitialize(), Initialize(), Destroy(), GetValuesHook();
  122. static String MyStrncpy(), StorePiecesInString();
  123. static Boolean SetValues(), WriteToFile();
  124. extern int errno, sys_nerr;
  125. extern char* sys_errlist[];
  126.  
  127. #define superclass        (&textSrcClassRec)
  128. MyAsciiSrcClassRec myasciiSrcClassRec = {
  129.   {
  130. /* core_class fields */    
  131.     /* superclass          */    (WidgetClass) superclass,
  132.     /* class_name          */    "myAsciiSrc",
  133.     /* widget_size          */    sizeof(MyAsciiSrcRec),
  134.     /* class_initialize       */    ClassInitialize,
  135.     /* class_part_initialize    */    NULL,
  136.     /* class_inited           */    FALSE,
  137.     /* initialize          */    Initialize,
  138.     /* initialize_hook        */    NULL,
  139.     /* realize              */    NULL,
  140.     /* actions              */    NULL,
  141.     /* num_actions          */    0,
  142.     /* resources          */    resources,
  143.     /* num_resources          */    XtNumber(resources),
  144.     /* xrm_class          */    NULLQUARK,
  145.     /* compress_motion          */    FALSE,
  146.     /* compress_exposure      */    FALSE,
  147.     /* compress_enterleave    */    FALSE,
  148.     /* visible_interest          */    FALSE,
  149.     /* destroy              */    Destroy,
  150.     /* resize              */    NULL,
  151.     /* expose              */    NULL,
  152.     /* set_values          */    SetValues,
  153.     /* set_values_hook        */    NULL,
  154.     /* set_values_almost    */    NULL,
  155.     /* get_values_hook        */    GetValuesHook,
  156.     /* accept_focus         */    NULL,
  157.     /* version            */    XtVersion,
  158.     /* callback_private       */    NULL,
  159.     /* tm_table               */    NULL,
  160.     /* query_geometry        */    NULL,
  161.     /* display_accelerator    */    NULL,
  162.     /* extension        */    NULL
  163.   },
  164. /* textSrc_class fields */
  165.   {
  166.     /* Read                     */      ReadText,
  167.     /* Replace                  */      ReplaceText,
  168.     /* Scan                     */      Scan,
  169.     /* Search                   */      Search,
  170.     /* SetSelection             */      XtInheritSetSelection,
  171.     /* ConvertSelection         */      XtInheritConvertSelection
  172.   },
  173. /* asciiSrc_class fields */
  174.   {
  175.     /* Keep the compiler happy */       NULL
  176.   }
  177. };
  178.  
  179. WidgetClass myasciiSrcObjectClass = (WidgetClass)&myasciiSrcClassRec;
  180.  
  181. /************************************************************
  182.  *
  183.  * Semi-Public Interfaces.
  184.  *
  185.  ************************************************************/
  186.  
  187. /*      Function Name: ClassInitialize
  188.  *      Description: Class Initialize routine, called only once.
  189.  *      Arguments: none.
  190.  *      Returns: none.
  191.  */
  192.  
  193. static void
  194. ClassInitialize()
  195. {
  196.   XawInitializeWidgetSet();
  197.   XtAddConverter( XtRString, XtRAsciiType, CvtStringToAsciiType,
  198.          NULL, (Cardinal) 0);
  199. }
  200.  
  201. /*      Function Name: Initialize
  202.  *      Description: Initializes the simple menu widget
  203.  *      Arguments: request - the widget requested by the argument list.
  204.  *                 new     - the new widget with both resource and non
  205.  *                           resource values.
  206.  *      Returns: none.
  207.  */
  208.  
  209. /* ARGSUSED */
  210. static void
  211. Initialize(request, new)
  212. Widget request, new;
  213. {
  214.   MyAsciiSrcObject src = (MyAsciiSrcObject) new;
  215.   FILE * file;
  216.  
  217. /*
  218.  * Set correct flags (override resources) depending upon widget class.
  219.  */
  220.  
  221. #ifdef ASCII_DISK
  222.   if (XtIsSubclass(XtParent(new), asciiDiskWidgetClass)) {
  223.     src->ascii_src.type = XawAsciiFile;
  224.     src->ascii_src.string = src->ascii_src.filename;
  225.   }
  226. #endif
  227.  
  228. #ifdef ASCII_STRING
  229.   if (XtIsSubclass(XtParent(new), asciiStringWidgetClass)) {
  230.     src->ascii_src.use_string_in_place = TRUE;
  231.     src->ascii_src.type = XawAsciiString;
  232.   }
  233. #endif
  234.  
  235.   src->ascii_src.changes = FALSE;
  236.   src->ascii_src.allocated_string = FALSE;
  237.  
  238.   file = InitStringOrFile(src, src->ascii_src.type == XawAsciiFile);
  239.   LoadPieces(src, file, NULL);
  240.  
  241.   if (file != NULL) fclose(file);
  242. }
  243.  
  244. /*    Function Name: ReadText
  245.  *    Description: This function reads the source.
  246.  *    Arguments: w - the AsciiSource widget.
  247.  *                 pos - position of the text to retreive.
  248.  * RETURNED        text - text block that will contain returned text.
  249.  *                 length - maximum number of characters to read.
  250.  *    Returns: The number of characters read into the buffer.
  251.  */
  252.  
  253. static XawTextPosition
  254. ReadText(w, pos, text, length)
  255. Widget w;
  256. XawTextPosition pos;
  257. XawTextBlock *text;    
  258. int length;        
  259. {
  260.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  261.   XawTextPosition count, start;
  262.   Piece * piece = FindPiece(src, pos, &start);
  263.     
  264.   text->firstPos = pos;
  265.   text->ptr = piece->text + (pos - start);
  266.   count = piece->used - (pos - start);
  267.   text->length = (length > count) ? count : length;
  268.   return(pos + text->length);
  269. }
  270.  
  271. /*    Function Name: ReplaceText.
  272.  *    Description: Replaces a block of text with new text.
  273.  *    Arguments: w - the AsciiSource widget.
  274.  *                 startPos, endPos - ends of text that will be removed.
  275.  *                 text - new text to be inserted into buffer at startPos.
  276.  *    Returns: XawEditError or XawEditDone.
  277.  */
  278.  
  279. /*ARGSUSED*/
  280. static int 
  281. ReplaceText (w, startPos, endPos, text)
  282. Widget w;
  283. XawTextPosition startPos, endPos;
  284. XawTextBlock *text;
  285. {
  286.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  287.   Piece *start_piece, *end_piece, *temp_piece;
  288.   XawTextPosition start_first, end_first;
  289.   int length, firstPos;
  290.  
  291. /*
  292.  * Editing a read only source is not allowed.
  293.  */
  294.  
  295.   if (src->text_src.edit_mode == XawtextRead) 
  296.     return(XawEditError);
  297.  
  298.   start_piece = FindPiece(src, startPos, &start_first);
  299.   end_piece = FindPiece(src, endPos, &end_first);
  300.  
  301.   src->ascii_src.changes = TRUE; /* We have changed the buffer. */
  302.  
  303. /* 
  304.  * Remove Old Stuff. 
  305.  */
  306.  
  307.   if (start_piece != end_piece) {
  308.     temp_piece = start_piece->next;
  309.  
  310. /*
  311.  * If empty and not the only piece then remove it. 
  312.  */
  313.  
  314.     if ( ((start_piece->used = startPos - start_first) == 0) &&
  315.      !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
  316.       RemovePiece(src, start_piece);
  317.  
  318.     while (temp_piece != end_piece) {
  319.       temp_piece = temp_piece->next;
  320.       RemovePiece(src, temp_piece->prev);
  321.     }
  322.     end_piece->used -= endPos - end_first;
  323.     if (end_piece->used != 0)
  324.       MyStrncpy(end_piece->text, (end_piece->text + endPos - end_first),
  325.         (int) end_piece->used);
  326.   }
  327.   else {            /* We are fully in one piece. */
  328.     if ( (start_piece->used -= endPos - startPos) == 0) {
  329.       if ( !((start_piece->next == NULL) && (start_piece->prev == NULL)) )
  330.     RemovePiece(src, start_piece);
  331.     }
  332.     else {
  333.       MyStrncpy(start_piece->text + (startPos - start_first),
  334.         start_piece->text + (endPos - start_first),
  335.         (int) (start_piece->used - (startPos - start_first)) );
  336.       if ( src->ascii_src.use_string_in_place && 
  337.        ((src->ascii_src.length - (endPos - startPos)) < 
  338.         (src->ascii_src.piece_size - 1)) ) 
  339.     start_piece->text[src->ascii_src.length - (endPos - startPos)] = '\0';
  340.     }
  341.   }
  342.  
  343.   src->ascii_src.length += -(endPos - startPos) + text->length;
  344.  
  345.   if ( text->length != 0) {
  346.  
  347.     /* 
  348.      * Put in the New Stuff.
  349.      */
  350.     
  351.     start_piece = FindPiece(src, startPos, &start_first);
  352.     
  353.     length = text->length;
  354.     firstPos = text->firstPos;
  355.     
  356.     while (length > 0) {
  357.       char * ptr;
  358.       int fill;
  359.       
  360.       if (src->ascii_src.use_string_in_place) {
  361.     if (start_piece->used == (src->ascii_src.piece_size - 1)) {
  362.       /*
  363.        * If we are in ascii string emulation mode. Then the
  364.        *  string is not allowed to grow.
  365.        */
  366.       start_piece->used = src->ascii_src.length = 
  367.                                              src->ascii_src.piece_size - 1;
  368.       start_piece->text[src->ascii_src.length] = '\0';
  369.       return(XawEditError);
  370.     }
  371.       }
  372.  
  373.  
  374.       if (start_piece->used == src->ascii_src.piece_size) {
  375.     BreakPiece(src, start_piece);
  376.     start_piece = FindPiece(src, startPos, &start_first);
  377.       }
  378.  
  379.       fill = Min((int)(src->ascii_src.piece_size - start_piece->used), length);
  380.       
  381.       ptr = start_piece->text + (startPos - start_first);
  382.       MyStrncpy(ptr + fill, ptr, 
  383.         (int) start_piece->used - (startPos - start_first));
  384.       strncpy(ptr, text->ptr + firstPos, fill);
  385.       
  386.       startPos += fill;
  387.       firstPos += fill;
  388.       start_piece->used += fill;
  389.       length -= fill;
  390.     }
  391.   }
  392.  
  393.   if (src->ascii_src.use_string_in_place)
  394.     start_piece->text[start_piece->used] = '\0';
  395.  
  396.   XtCallCallbacks(w, XtNcallback, NULL); /* Call callbacks, we have changed 
  397.                         the buffer. */
  398.  
  399.   return(XawEditDone);
  400. }
  401.  
  402. /*    Function Name: Scan
  403.  *    Description: Scans the text source for the number and type
  404.  *                   of item specified.
  405.  *    Arguments: w - the AsciiSource widget.
  406.  *                 position - the position to start scanning.
  407.  *                 type - type of thing to scan for.
  408.  *                 dir - direction to scan.
  409.  *                 count - which occurance if this thing to search for.
  410.  *                 include - whether or not to include the character found in
  411.  *                           the position that is returned. 
  412.  *    Returns: the position of the item found.
  413.  *
  414.  * Note: While there are only 'n' characters in the file there are n+1 
  415.  *       possible cursor positions (one before the first character and
  416.  *       one after the last character.
  417.  */
  418.  
  419. static 
  420. XawTextPosition 
  421. Scan (w, position, type, dir, count, include)
  422. Widget                w;
  423. XawTextPosition       position;
  424. XawTextScanType       type;
  425. XawTextScanDirection  dir;
  426. int               count;
  427. Boolean                  include;
  428. {
  429.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  430.   register int inc;
  431.   Piece * piece;
  432.   XawTextPosition first, first_eol_position;
  433.   register char * ptr;
  434.  
  435.   if (type == XawstAll) {    /* Optomize this common case. */
  436.     if (dir == XawsdRight)
  437.       return(src->ascii_src.length);
  438.     return(0);            /* else. */
  439.   }
  440.  
  441.   if (position > src->ascii_src.length)
  442.     position = src->ascii_src.length;
  443.  
  444.   if ( dir == XawsdRight ) {
  445.     if (position == src->ascii_src.length)
  446. /*
  447.  * Scanning right from src->ascii_src.length???
  448.  */
  449.       return(src->ascii_src.length);
  450.     inc = 1;
  451.   }
  452.   else {
  453.     if (position == 0)
  454.       return(0);        /* Scanning left from 0??? */
  455.     inc = -1;
  456.     position--;
  457.   }
  458.  
  459.   piece = FindPiece(src, position, &first);
  460.  
  461. /*
  462.  * If the buffer is empty then return 0. 
  463.  */
  464.  
  465.   if ( piece->used == 0 ) return(0); 
  466.  
  467.   ptr = (position - first) + piece->text;
  468.  
  469.   switch (type) {
  470.   case XawstEOL: 
  471.   case XawstParagraph: 
  472.   case XawstWhiteSpace: 
  473.     for ( ; count > 0 ; count-- ) {
  474.       Boolean non_space = FALSE, first_eol = TRUE;
  475.       while (TRUE) {
  476.     register unsigned char c = *ptr;
  477.  
  478.     ptr += inc;
  479.     position += inc;
  480.     
  481.     if (type == XawstWhiteSpace) {
  482.       if (isspace(c)) {
  483.         if (non_space) 
  484.           break;
  485.       }
  486.       else
  487.         non_space = TRUE;
  488.     }
  489.     else if (type == XawstEOL) {
  490.       if (c == '\n') break;
  491.     }
  492.     else { /* XawstParagraph */
  493.       if (first_eol) {
  494.         if (c == '\n') {
  495.           first_eol_position = position;
  496.           first_eol = FALSE;
  497.         }
  498.       }
  499.       else
  500.         if ( c == '\n') 
  501.           break;
  502.         else if ( !isspace(c) )
  503.           first_eol = TRUE;
  504.     }
  505.           
  506.  
  507.     if ( ptr < piece->text ) {
  508.       piece = piece->prev;
  509.       if (piece == NULL)    /* Begining of text. */
  510.         return(0);
  511.       ptr = piece->text + piece->used - 1;
  512.     }
  513.     else if ( ptr >= (piece->text + piece->used) ) {
  514.       piece = piece->next;
  515.       if (piece == NULL)    /* End of text. */
  516.         return(src->ascii_src.length);
  517.       ptr = piece->text;
  518.     }
  519.       }
  520.     }
  521.     if (!include) {
  522.       if ( type == XawstParagraph)
  523.     position = first_eol_position;
  524.       position -= inc;
  525.     }
  526.     break;
  527.   case XawstPositions: 
  528.     position += count * inc;
  529.     break;
  530. /*  case XawstAll:        ---- handled in special code above */
  531.   }
  532.  
  533.   if ( dir == XawsdLeft )
  534.     position++;
  535.  
  536.   if (position >= src->ascii_src.length)
  537.     return(src->ascii_src.length);
  538.   if (position < 0)
  539.     return(0);
  540.  
  541.   return(position);
  542. }
  543.  
  544. /*    Function Name: Search
  545.  *    Description: Searchs the text source for the text block passed
  546.  *    Arguments: w - the AsciiSource Widget.
  547.  *                 position - the position to start scanning.
  548.  *                 dir - direction to scan.
  549.  *                 text - the text block to search for.
  550.  *    Returns: the position of the item found.
  551.  */
  552.  
  553. static XawTextPosition 
  554. Search(w, position, dir, text)
  555. Widget                w;
  556. XawTextPosition       position;
  557. XawTextScanDirection  dir;
  558. XawTextBlock *        text;
  559. {
  560.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  561.   register int inc, count = 0;
  562.   register char * ptr;
  563.   Piece * piece;
  564.   char * buf;
  565.   XawTextPosition first;
  566.  
  567.   if ( dir == XawsdRight )
  568.     inc = 1;
  569.   else {
  570.     inc = -1;
  571.     if (position == 0)
  572.       return(XawTextSearchError);    /* scanning left from 0??? */
  573.     position--;
  574.   }
  575.  
  576.   buf = XtMalloc(sizeof(unsigned char) * text->length);
  577.   strncpy(buf, (text->ptr + text->firstPos), text->length);
  578.   piece = FindPiece(src, position, &first);
  579.   ptr = (position - first) + piece->text;
  580.  
  581.   while (TRUE) {
  582.     if (tolower(*ptr) == tolower(((dir == XawsdRight) ? *(buf + count) 
  583.                              : *(buf + text->length - count - 1))) ) {
  584.       if (count == (text->length - 1))
  585.     break;
  586.       else
  587.     count++;
  588.     }
  589.     else {
  590.       if (count != 0) {
  591.     position -=inc * count;
  592.     ptr -= inc * count;
  593.       }
  594.       count = 0;
  595.     }
  596.  
  597.     ptr += inc;
  598.     position += inc;
  599.     
  600.     while ( ptr < piece->text ) {
  601.       piece = piece->prev;
  602.       if (piece == NULL) {    /* Begining of text. */
  603.     XtFree(buf);
  604.     return(XawTextSearchError);
  605.       }
  606.       ptr = piece->text + piece->used - 1;
  607.     }
  608.    
  609.     while ( ptr >= (piece->text + piece->used) ) {
  610.       piece = piece->next;
  611.       if (piece == NULL) {    /* End of text. */
  612.     XtFree(buf);
  613.     return(XawTextSearchError);
  614.       }
  615.       ptr = piece->text;
  616.     }
  617.   }
  618.  
  619.   XtFree(buf);
  620.   if (dir == XawsdLeft)
  621.     return(position);
  622.   return(position - (text->length - 1));
  623. }
  624.  
  625. /*    Function Name: SetValues
  626.  *    Description: Sets the values for the AsciiSource.
  627.  *    Arguments: current - current state of the widget.
  628.  *                 request - what was requested.
  629.  *                 new - what the widget will become.
  630.  *    Returns: True if redisplay is needed.
  631.  */
  632.  
  633. /* ARGSUSED */
  634. static Boolean
  635. SetValues(current, request, new, args, num_args)
  636. Widget current, request, new;
  637. ArgList args;
  638. Cardinal * num_args;
  639. {
  640.   MyAsciiSrcObject src =      (MyAsciiSrcObject) new;
  641.   MyAsciiSrcObject old_src = (MyAsciiSrcObject) current;
  642.   Boolean total_reset = FALSE, string_set = FALSE;
  643.   FILE * file;
  644.   int i;
  645.  
  646.   if ( old_src->ascii_src.use_string_in_place != 
  647.        src->ascii_src.use_string_in_place ) {
  648.       XtAppWarning( XtWidgetToApplicationContext(new),
  649.        "AsciiSrc: The XtNuseStringInPlace resource may not be changed.");
  650.        src->ascii_src.use_string_in_place = 
  651.        old_src->ascii_src.use_string_in_place;
  652.   }
  653.  
  654.   for (i = 0; i < *num_args ; i++ ) 
  655.       if (streq(args[i].name, XtNstring)) {
  656.       string_set = TRUE;
  657.       break;
  658.       }
  659.   
  660.   if ( string_set || (old_src->ascii_src.type != src->ascii_src.type) ) {
  661.     RemoveOldStringOrFile(old_src, string_set); /* remove old info. */
  662.     file = InitStringOrFile(src, string_set);    /* Init new info. */
  663.     LoadPieces(src, file, NULL);    /* load new info into internal buffers. */
  664.     if (file != NULL) fclose(file);
  665.     XawTextSetSource( XtParent(new), new, 0);   /* Tell text widget
  666.                            what happened. */
  667.     total_reset = TRUE;
  668.   }
  669.  
  670.   if ( old_src->ascii_src.ascii_length != src->ascii_src.ascii_length ) 
  671.       src->ascii_src.piece_size = src->ascii_src.ascii_length;
  672.  
  673.   if ( !total_reset && 
  674.       (old_src->ascii_src.piece_size != src->ascii_src.piece_size) ) {
  675.       String string = StorePiecesInString(old_src);
  676.       FreeAllPieces(old_src);
  677.       LoadPieces(src, NULL, string);
  678.       XtFree(string);
  679.   }
  680.  
  681.   return(FALSE);
  682. }
  683.  
  684. /*    Function Name: GetValuesHook
  685.  *    Description: This is a get values hook routine that sets the
  686.  *                   values specific to the ascii source.
  687.  *    Arguments: w - the AsciiSource Widget.
  688.  *                 args - the argument list.
  689.  *                 num_args - the number of args.
  690.  *    Returns: none.
  691.  */
  692.  
  693. static void
  694. GetValuesHook(w, args, num_args)
  695. Widget w;
  696. ArgList args;
  697. Cardinal * num_args;
  698. {
  699.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  700.   register int i;
  701.  
  702.   if (src->ascii_src.type == XawAsciiString) {
  703.     for (i = 0; i < *num_args ; i++ ) 
  704.       if (streq(args[i].name, XtNstring)) {
  705.       if (src->ascii_src.use_string_in_place) {
  706.           *((char **) args[i].value) = src->ascii_src.first_piece->text;
  707.       }
  708.       else {
  709.           if (XawAsciiSave(w))    /* If save sucessful. */
  710.           *((char **) args[i].value) = src->ascii_src.string;
  711.       }
  712.     break;
  713.       }
  714.   }
  715. }    
  716.  
  717. /*    Function Name: Destroy
  718.  *    Description: Destroys an ascii source (frees all data)
  719.  *    Arguments: src - the Ascii source Widget to free.
  720.  *    Returns: none.
  721.  */
  722.  
  723. static void 
  724. Destroy (w)
  725. Widget w;
  726. {
  727.   RemoveOldStringOrFile((MyAsciiSrcObject) w, True);
  728. }
  729.  
  730. /************************************************************
  731.  *
  732.  * Public routines 
  733.  *
  734.  ************************************************************/
  735.  
  736. /*    Function Name: MyAsciiSourceFreeString
  737.  *    Description: Frees the string returned by a get values call
  738.  *                   on the string when the source is of type string.
  739.  *    Arguments: w - the AsciiSrc widget.
  740.  *    Returns: none.
  741.  */
  742.  
  743. void
  744. #if NeedFunctionPrototypes
  745. MyAsciiSourceFreeString(Widget w)
  746. #else
  747. MyAsciiSourceFreeString(w)
  748. Widget w;
  749. #endif
  750. {
  751.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  752.  
  753.   if (src->ascii_src.allocated_string && src->ascii_src.type != XawAsciiFile) {
  754.     src->ascii_src.allocated_string = FALSE;
  755.     XtFree(src->ascii_src.string);
  756.     src->ascii_src.string = NULL;
  757.   }
  758. }
  759.  
  760. /*    Function Name: MyAsciiSave
  761.  *    Description: Saves all the pieces into a file or string as required.
  762.  *    Arguments: w - the asciiSrc Widget.
  763.  *    Returns: TRUE if the save was successful.
  764.  */
  765.  
  766. Boolean
  767. #if NeedFunctionPrototypes
  768. MyAsciiSave(Widget w)
  769. #else
  770. MyAsciiSave(w)
  771. Widget w;
  772. #endif
  773. {
  774.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  775.  
  776. /*
  777.  * If using the string in place then there is no need to play games
  778.  * to get the internal info into a readable string.
  779.  */
  780.  
  781.   if (src->ascii_src.use_string_in_place) 
  782.     return(TRUE);
  783.  
  784.   if (src->ascii_src.type == XawAsciiFile) {
  785.     char * string;
  786.  
  787.     if (!src->ascii_src.changes)         /* No changes to save. */
  788.       return(TRUE);
  789.  
  790.     string = StorePiecesInString(src);
  791.  
  792.     if (WriteToFile(string, src->ascii_src.string) == FALSE) {
  793.       XtFree(string);
  794.       return(FALSE);
  795.     }
  796.     XtFree(string);
  797.   }
  798.   else {            /* This is a string widget. */
  799.     if (src->ascii_src.allocated_string == TRUE) 
  800.       XtFree(src->ascii_src.string);
  801.     else
  802.       src->ascii_src.allocated_string = TRUE;
  803.     
  804.     src->ascii_src.string = StorePiecesInString(src);
  805.   }
  806.   src->ascii_src.changes = FALSE;
  807.   return(TRUE);
  808. }
  809.  
  810. /*    Function Name: MyAsciiSaveAsFile
  811.  *    Description: Save the current buffer as a file.
  812.  *    Arguments: w - the AsciiSrc widget.
  813.  *                 name - name of the file to save this file into.
  814.  *    Returns: True if the save was sucessful.
  815.  */
  816.  
  817. Boolean
  818. #if NeedFunctionPrototypes
  819. #ifdef sgi
  820. MyAsciiSaveAsFile(Widget w, String name)
  821. #else
  822. MyAsciiSaveAsFile(Widget w, _Xconst char* name)
  823. #endif
  824. #else
  825. MyAsciiSaveAsFile(w, name)
  826. Widget w;
  827. String name;
  828. #endif
  829. {
  830.   MyAsciiSrcObject src = (MyAsciiSrcObject) w;
  831.   String string;
  832.   Boolean ret;
  833.  
  834.   string = StorePiecesInString(src); 
  835.  
  836.   ret = WriteToFile(string, name);
  837.   XtFree(string);
  838.   return(ret);
  839. }
  840.  
  841. /*    Function Name: XawAsciiSourceChanged
  842.  *    Description: Returns true if the source has changed since last saved.
  843.  *    Arguments: w - the ascii source widget.
  844.  *    Returns: a Boolean (see description).
  845.  */
  846.  
  847. Boolean 
  848. #if NeedFunctionPrototypes
  849. MyAsciiSourceChanged(Widget w)
  850. #else
  851. MyAsciiSourceChanged(w)
  852. Widget w;
  853. #endif
  854. {
  855.   return( ((MyAsciiSrcObject) w)->ascii_src.changes );
  856. }
  857.   
  858. /************************************************************
  859.  *
  860.  * Private Functions.
  861.  *
  862.  ************************************************************/
  863.  
  864. static void
  865. RemoveOldStringOrFile(src, checkString) 
  866. MyAsciiSrcObject src;
  867. Boolean checkString;
  868. {
  869.   FreeAllPieces(src);
  870.  
  871.   if (checkString && src->ascii_src.allocated_string) {
  872.     XtFree(src->ascii_src.string);
  873.     src->ascii_src.allocated_string = False;
  874.     src->ascii_src.string = NULL;
  875.   }
  876. }
  877.  
  878. /*    Function Name: WriteToFile
  879.  *    Description: Write the string specified to the begining of the file
  880.  *                   specified.
  881.  *    Arguments: string - string to write.
  882.  *                 name - the name of the file
  883.  *    Returns: returns TRUE if sucessful, FALSE otherwise.
  884.  */
  885.  
  886. static Boolean
  887. WriteToFile(string, name)
  888. String string, name;
  889. {
  890.   int fd;
  891.   
  892.   if ( ((fd = creat(name, 0666)) == -1 ) ||
  893.        (write(fd, string, sizeof(unsigned char) * strlen(string)) == -1) )
  894.     return(FALSE);
  895.  
  896.   if ( close(fd) == -1 ) 
  897.     return(FALSE);
  898.  
  899.   return(TRUE);
  900. }
  901.  
  902. /*    Function Name: StorePiecesInString
  903.  *    Description: store the pieces in memory into a standard ascii string.
  904.  *    Arguments: data - the ascii pointer data.
  905.  *    Returns: none.
  906.  */
  907.  
  908. static String
  909. StorePiecesInString(src)
  910. MyAsciiSrcObject src;
  911. {
  912.   String string;
  913.   XawTextPosition first;
  914.   Piece * piece;
  915.  
  916.   string = XtMalloc(sizeof(unsigned char) * src->ascii_src.length + 1);
  917.   
  918.   for (first = 0, piece = src->ascii_src.first_piece ; piece != NULL; 
  919.        first += piece->used, piece = piece->next) 
  920.     strncpy(string + first, piece->text, piece->used);
  921.  
  922.   string[src->ascii_src.length] = '\0';    /* NULL terminate this sucker. */
  923.  
  924. /*
  925.  * This will refill all pieces to capacity. 
  926.  */
  927.  
  928.   if (src->ascii_src.data_compression) {    
  929.     FreeAllPieces(src);
  930.     LoadPieces(src, NULL, string);
  931.   }
  932.  
  933.   return(string);
  934. }
  935.  
  936. /*    Function Name: InitStringOrFile.
  937.  *    Description: Initializes the string or file.
  938.  *    Arguments: src - the AsciiSource.
  939.  *    Returns: none - May exit though.
  940.  */
  941.  
  942. static FILE *
  943. InitStringOrFile(src, newString)
  944. MyAsciiSrcObject src;
  945. Boolean newString;
  946. {
  947.     char * open_mode;
  948.     FILE * file;
  949.     char fileName[TMPSIZ];
  950.  
  951.     if (src->ascii_src.type == XawAsciiString) {
  952.  
  953.     if (src->ascii_src.string == NULL)
  954.         src->ascii_src.length = 0;
  955.  
  956.     else if (! src->ascii_src.use_string_in_place) {
  957.         src->ascii_src.string = XtNewString(src->ascii_src.string);
  958.         src->ascii_src.allocated_string = True;
  959.         src->ascii_src.length = strlen(src->ascii_src.string);
  960.     }
  961.  
  962.     if (src->ascii_src.use_string_in_place) {
  963.         src->ascii_src.length = strlen(src->ascii_src.string);
  964.         /* In case the length resource is incorrectly set */
  965.         if (src->ascii_src.length > src->ascii_src.ascii_length)
  966.         src->ascii_src.ascii_length = src->ascii_src.length;
  967.  
  968.         if (src->ascii_src.ascii_length == MAGIC_VALUE) 
  969.         src->ascii_src.piece_size = src->ascii_src.length;
  970.         else
  971.         src->ascii_src.piece_size = src->ascii_src.ascii_length + 1;
  972.     }
  973.         
  974.     return(NULL);
  975.     }
  976.  
  977. /*
  978.  * type is XawAsciiFile.
  979.  */
  980.     
  981.     src->ascii_src.is_tempfile = FALSE;
  982.  
  983.     switch (src->text_src.edit_mode) {
  984.     case XawtextRead:
  985.     if (src->ascii_src.string == NULL)
  986.         XtErrorMsg("NoFile", "asciiSourceCreate", "XawError",
  987.              "Creating a read only disk widget and no file specified.",
  988.                NULL, 0);
  989.     open_mode = "r";
  990.     break;
  991.     case XawtextAppend:
  992.     case XawtextEdit:
  993.     if (src->ascii_src.string == NULL) {
  994.         src->ascii_src.string = fileName;
  995.         (void) tmpnam(src->ascii_src.string);
  996.         src->ascii_src.is_tempfile = TRUE;
  997.         open_mode = "w";
  998.     } else
  999.         open_mode = "r+";
  1000.     break;
  1001.     default:
  1002.     XtErrorMsg("badMode", "asciiSourceCreate", "XawError",
  1003.         "Bad editMode for ascii source; must be Read, Append or Edit.",
  1004.            NULL, NULL);
  1005.     }
  1006.  
  1007.     /* Allocate new memory for the temp filename, because it is held in
  1008.      * a stack variable, not static memory.  This widget does not need
  1009.      * to keep the private state field is_tempfile -- it is only accessed
  1010.      * in this routine, and its former setting is unused.
  1011.      */
  1012.     if (newString || src->ascii_src.is_tempfile) {
  1013.     src->ascii_src.string = XtNewString(src->ascii_src.string);
  1014.     src->ascii_src.allocated_string = TRUE;
  1015.     }
  1016.     
  1017.     if (!src->ascii_src.is_tempfile) {
  1018.     if ((file = fopen(src->ascii_src.string, open_mode)) != 0) {
  1019.         (void) fseek(file, 0L, 2);
  1020.         src->ascii_src.length = ftell(file);
  1021.         return file;
  1022.     } else {
  1023.         String params[2];
  1024.         Cardinal num_params = 2;
  1025.         char msg[11];
  1026.         
  1027.         params[0] = src->ascii_src.string;
  1028.         if (errno <= sys_nerr)
  1029.         params[1] = sys_errlist[errno];
  1030.         else {
  1031.         sprintf(msg, "errno=%.4d", errno);
  1032.         params[1] = msg;
  1033.         }
  1034.         XtAppWarningMsg(XtWidgetToApplicationContext((Widget)src),
  1035.                 "openError", "asciiSourceCreate", "XawWarning",
  1036.                 "Cannot open file %s; %s", params, &num_params);
  1037.     }
  1038.     } 
  1039.     src->ascii_src.length = 0;
  1040.     return((FILE *)NULL);
  1041. }
  1042.  
  1043. static void
  1044. LoadPieces(src, file, string)
  1045. MyAsciiSrcObject src;
  1046. FILE * file;
  1047. char * string;
  1048. {
  1049.   char *local_str, *ptr;
  1050.   register Piece * piece = NULL;
  1051.   XawTextPosition left;
  1052.  
  1053.   if (string == NULL) {
  1054.     if (src->ascii_src.type == XawAsciiFile) {
  1055.       local_str = XtMalloc((src->ascii_src.length + 1) *sizeof(unsigned char));
  1056.       if (src->ascii_src.length != 0) {
  1057.     fseek(file, 0L, 0);
  1058.     if ( fread(local_str, sizeof(unsigned char),
  1059.            src->ascii_src.length, file) != src->ascii_src.length ) 
  1060.       XtErrorMsg("readError", "asciiSourceCreate", "XawError",
  1061.              "fread returned error.", NULL, NULL);
  1062.       }
  1063.       local_str[src->ascii_src.length] = '\0';
  1064.     }
  1065.     else
  1066.       local_str = src->ascii_src.string;
  1067.   }
  1068.   else
  1069.     local_str = string;
  1070.  
  1071. /*
  1072.  * If we are using teh string in place then set the other fields as follows:
  1073.  *
  1074.  * piece_size = length;
  1075.  * piece->used = src->ascii_src.length;
  1076.  */
  1077.   
  1078.   if (src->ascii_src.use_string_in_place) {
  1079.     piece = AllocNewPiece(src, piece);
  1080.     piece->used = Min(src->ascii_src.length, src->ascii_src.piece_size);
  1081.     piece->text = src->ascii_src.string;
  1082.     return;
  1083.   }
  1084.  
  1085.   ptr = local_str;
  1086.   left = src->ascii_src.length;
  1087.  
  1088.   do {
  1089.     piece = AllocNewPiece(src, piece);
  1090.  
  1091.     piece->text = XtMalloc(src->ascii_src.piece_size * sizeof(unsigned char));
  1092.     piece->used = Min(left, src->ascii_src.piece_size);
  1093.     if (piece->used != 0)
  1094.       strncpy(piece->text, ptr, piece->used);
  1095.  
  1096.     left -= piece->used;
  1097.     ptr += piece->used;
  1098.   } while (left > 0);
  1099.  
  1100.   if ( (src->ascii_src.type == XawAsciiFile) && (string == NULL) )
  1101.     XtFree(local_str);
  1102. }
  1103.  
  1104. /*    Function Name: AllocNewPiece
  1105.  *    Description: Allocates a new piece of memory.
  1106.  *    Arguments: src - The AsciiSrc Widget.
  1107.  *                 prev - the piece just before this one, or NULL.
  1108.  *    Returns: the allocated piece.
  1109.  */
  1110.  
  1111. static Piece *
  1112. AllocNewPiece(src, prev)
  1113. MyAsciiSrcObject src;
  1114. Piece * prev;
  1115. {
  1116.   Piece * piece = XtNew(Piece);
  1117.  
  1118.   if (prev == NULL) {
  1119.     src->ascii_src.first_piece = piece;
  1120.     piece->next = NULL;
  1121.   }
  1122.   else {
  1123.     if (prev->next != NULL)
  1124.       (prev->next)->prev = piece;
  1125.     piece->next = prev->next;
  1126.     prev->next = piece;
  1127.   }
  1128.   
  1129.   piece->prev = prev;
  1130.  
  1131.   return(piece);
  1132. }
  1133.  
  1134. /*    Function Name: FreeAllPieces
  1135.  *    Description: Frees all the pieces
  1136.  *    Arguments: src - The AsciiSrc Widget.
  1137.  *    Returns: none.
  1138.  */
  1139.  
  1140. static void 
  1141. FreeAllPieces(src)
  1142. MyAsciiSrcObject src;
  1143. {
  1144.   Piece * next, * first = src->ascii_src.first_piece;
  1145.  
  1146.   if (first->prev != NULL)
  1147.     printf("Programmer Botch in FreeAllPieces, there may be a memory leak.\n");
  1148.  
  1149.   for ( ; first != NULL ; first = next ) {
  1150.     next = first->next;
  1151.     RemovePiece(src, first);
  1152.   }
  1153. }
  1154.   
  1155. /*    Function Name: RemovePiece
  1156.  *    Description: Removes a piece from the list.
  1157.  *    Arguments: 
  1158.  *                 piece - the piece to remove.
  1159.  *    Returns: none.
  1160.  */
  1161.  
  1162. static void
  1163. RemovePiece(src, piece)
  1164. MyAsciiSrcObject src;
  1165. Piece * piece;
  1166. {
  1167.   if (piece->prev == NULL)
  1168.     src->ascii_src.first_piece = piece->next;
  1169.   else
  1170.     (piece->prev)->next = piece->next;
  1171.  
  1172.   if (piece->next != NULL)
  1173.     (piece->next)->prev = piece->prev;
  1174.  
  1175.   if (!src->ascii_src.use_string_in_place)
  1176.     XtFree(piece->text);
  1177.  
  1178.   XtFree((char *)piece);
  1179. }
  1180.  
  1181. /*    Function Name: FindPiece
  1182.  *    Description: Finds the piece containing the position indicated.
  1183.  *    Arguments: src - The AsciiSrc Widget.
  1184.  *                 position - the position that we are searching for.
  1185.  * RETURNED        first - the position of the first character in this piece.
  1186.  *    Returns: piece - the piece that contains this position.
  1187.  */
  1188.  
  1189. static Piece *
  1190. FindPiece(src, position, first)
  1191. MyAsciiSrcObject src;
  1192. XawTextPosition position, *first;
  1193. {
  1194.   Piece * old_piece, * piece = src->ascii_src.first_piece;
  1195.   XawTextPosition temp;
  1196.  
  1197.   for ( temp = 0 ; piece != NULL ; temp += piece->used, piece = piece->next ) {
  1198.     *first = temp;
  1199.     old_piece = piece;
  1200.  
  1201.     if ((temp + piece->used) > position) 
  1202.       return(piece);
  1203.   }
  1204.   return(old_piece);      /* if we run off the end the return the last piece */
  1205. }
  1206.     
  1207. /*    Function Name: MyStrncpy
  1208.  *    Description: Just like string copy, but slower and will always
  1209.  *                   work on overlapping strings.
  1210.  *    Arguments: (same as strncpy) - s1, s2 - strings to copy (2->1).
  1211.  *                  n - the number of chars to copy.
  1212.  *    Returns: s1.
  1213.  */
  1214.  
  1215. static String
  1216. MyStrncpy(s1, s2, n)
  1217. char * s1, * s2;
  1218. int n;
  1219. {
  1220.   char * temp = XtMalloc(sizeof(unsigned char) * n);
  1221.  
  1222.   strncpy(temp, s2, n);        /* Saber has a bug that causes it to generate*/
  1223.   strncpy(s1, temp, n);        /* a bogus warning message here (CDP 6/32/89)*/
  1224.   XtFree(temp);
  1225.   return(s1);
  1226. }
  1227.   
  1228. /*    Function Name: BreakPiece
  1229.  *    Description: Breaks a full piece into two new pieces.
  1230.  *    Arguments: src - The AsciiSrc Widget.
  1231.  *                 piece - the piece to break.
  1232.  *    Returns: none.
  1233.  */
  1234.  
  1235. #define HALF_PIECE (src->ascii_src.piece_size/2)
  1236.  
  1237. static void
  1238. BreakPiece(src, piece)
  1239. MyAsciiSrcObject src;
  1240. Piece * piece;
  1241. {
  1242.   Piece * new = AllocNewPiece(src, piece);
  1243.   
  1244.   new->text = XtMalloc(src->ascii_src.piece_size * sizeof(unsigned char));
  1245.   strncpy(new->text, piece->text + HALF_PIECE,
  1246.       src->ascii_src.piece_size - HALF_PIECE);
  1247.   piece->used = HALF_PIECE;
  1248.   new->used = src->ascii_src.piece_size - HALF_PIECE; 
  1249. }
  1250.  
  1251. /* ARGSUSED */
  1252. static void
  1253. CvtStringToAsciiType(args, num_args, fromVal, toVal)
  1254. XrmValuePtr *args;        /* unused */
  1255. Cardinal    *num_args;    /* unused */
  1256. XrmValuePtr    fromVal;
  1257. XrmValuePtr    toVal;
  1258. {
  1259.   static XawAsciiType type;
  1260.   static XrmQuark  XtQEstring = NULLQUARK;
  1261.   static XrmQuark  XtQEfile;
  1262.   XrmQuark q;
  1263.   char lowerName[BUFSIZ];
  1264.  
  1265.   if (XtQEstring == NULLQUARK) {
  1266.     XtQEstring = XrmPermStringToQuark(XtEstring);
  1267.     XtQEfile   = XrmPermStringToQuark(XtEfile);
  1268.   }
  1269.  
  1270.   XmuCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
  1271.   q = XrmStringToQuark(lowerName);
  1272.  
  1273.   if (q == XtQEstring) type = XawAsciiString;
  1274.   if (q == XtQEfile)  type = XawAsciiFile;
  1275.  
  1276.   (*toVal).size = sizeof(XawAsciiType);
  1277.   (*toVal).addr = (XPointer) &type;
  1278.   return;
  1279. }
  1280.  
  1281. #if (defined(ASCII_STRING) || defined(ASCII_DISK))
  1282. #  include <X11/Xaw/Cardinals.h>
  1283. #endif
  1284.  
  1285. #ifdef ASCII_STRING
  1286. /************************************************************
  1287.  *
  1288.  * Compatability functions.
  1289.  *
  1290.  ************************************************************/
  1291.  
  1292. /*    Function Name: AsciiStringSourceCreate
  1293.  *    Description: Creates a string source.
  1294.  *    Arguments: parent - the widget that will own this source.
  1295.  *                 args, num_args - the argument list.
  1296.  *    Returns: a pointer to the new text source.
  1297.  */
  1298.  
  1299. Widget
  1300. MyStringSourceCreate(parent, args, num_args)
  1301. Widget parent;
  1302. ArgList args;
  1303. Cardinal num_args;
  1304. {
  1305.   XawTextSource src;
  1306.   ArgList ascii_args;
  1307.   Arg temp[2];
  1308.  
  1309.   XtSetArg(temp[0], XtNtype, XawAsciiString);
  1310.   XtSetArg(temp[1], XtNuseStringInPlace, TRUE);
  1311.   ascii_args = XtMergeArgLists(temp, TWO, args, num_args);
  1312.  
  1313.   src = XtCreateWidget("genericAsciiString", myasciiSrcObjectClass, parent,
  1314.                ascii_args, num_args + TWO);
  1315.   XtFree((char *)ascii_args);
  1316.   return(src);
  1317. }
  1318.  
  1319. /*
  1320.  * This is hacked up to try to emulate old functionality, it
  1321.  * may not work, as I have not old code to test it on.
  1322.  *
  1323.  * Chris D. Peterson  8/31/89.
  1324.  */
  1325.  
  1326. void 
  1327. MyTextSetLastPos (w, lastPos)
  1328. Widget w;
  1329. XawTextPosition lastPos;
  1330. {
  1331.   MyAsciiSrcObject src = (MyAsciiSrcObject) XawTextGetSource(w);
  1332.  
  1333.   src->ascii_src.piece_size = lastPos;
  1334. }
  1335. #endif /* ASCII_STRING */
  1336.  
  1337. #ifdef ASCII_DISK
  1338. /*    Function Name: AsciiDiskSourceCreate
  1339.  *    Description: Creates a disk source.
  1340.  *    Arguments: parent - the widget that will own this source.
  1341.  *                 args, num_args - the argument list.
  1342.  *    Returns: a pointer to the new text source.
  1343.  */
  1344.  
  1345. Widget
  1346. MyDiskSourceCreate(parent, args, num_args)
  1347. Widget parent;
  1348. ArgList args;
  1349. Cardinal num_args;
  1350. {
  1351.   XawTextSource src;
  1352.   ArgList ascii_args;
  1353.   Arg temp[1];
  1354.   register int i;
  1355.  
  1356.   XtSetArg(temp[0], XtNtype, XawAsciiFile);
  1357.   ascii_args = XtMergeArgLists(temp, ONE, args, num_args);
  1358.   num_args++;
  1359.  
  1360.   for (i = 0; i < num_args; i++) 
  1361.     if (streq(ascii_args[i].name, XtNfile) || 
  1362.               streq(ascii_args[i].name, XtCFile)) 
  1363.       ascii_args[i].name = XtNstring;
  1364.  
  1365.   src = XtCreateWidget("genericAsciiDisk", myasciiSrcObjectClass, parent,
  1366.                ascii_args, num_args);
  1367.   XtFree((char *)ascii_args);
  1368.   return(src);
  1369. }
  1370. #endif /* ASCII_DISK */
  1371.  
  1372.